home *** CD-ROM | disk | FTP | other *** search
/ AOL File Library: 2,801 to 2,900 / aol-file-protocol-4400-2801-to-2900.zip / AOLDLs / C++ Files Library / Graphic Gems I, II & III (C_C++) / Graphics Gems C Code.sea / GemsIII / accurate_scan / dblfixpoint.c next >
C/C++ Source or Header  |  1992-06-16  |  4KB  |  174 lines

  1. #include <stdio.h>
  2. #include "fixpoint.h"
  3.  
  4. static int verbose = 0;
  5.  
  6. /* The dblfixpoint representation is signed magnitude, with
  7.   hi is 2n bits of integer (n <= 16)
  8.   lo is 2m bits of fraction (m <=16)
  9. number = hi + lo * 2^(-2m)
  10. */
  11.  
  12. int fp_dblnegative(dblfixpoint x) { return (x.neg); }
  13.  
  14. dblfixpoint fp_dblnegate(dblfixpoint x)
  15. { x.neg = !x.neg;   return x; }
  16.  
  17. dblfixpoint fp_dblmultiply(fixpoint x, fixpoint y)
  18. {
  19.   dblfixpoint answer;
  20.   unsigned int a, b, c, d;
  21.   unsigned int xhi, xlo, yhi, ylo;
  22.  
  23.   xhi = (x<0) ? -fp_integer(x) : fp_integer(x);
  24.   yhi = (y<0) ? -fp_integer(y) : fp_integer(y);
  25.   xlo = fp_fraction(x);
  26.   ylo = fp_fraction(y);
  27.  
  28.   a = xhi * yhi;
  29.   b = xhi * ylo;
  30.   c = xlo * yhi;
  31.   d = xlo * ylo;
  32.  
  33.   a += ((b & HIMASK) >> LOBITS);
  34.   a += ((c & HIMASK) >> LOBITS);
  35.   b = (b & LOMASK) + (c & LOMASK) + ((d & HIMASK) >> LOBITS);
  36.   a += ((b & HIMASK) >> LOBITS);
  37.   answer.hi = a;
  38.   answer.lo = ((b & LOMASK) << LOBITS) | (d & LOMASK);
  39.   answer.neg = 0;
  40.  
  41.   if (((x<0) && (y>0)) || ((x>0) && (y<0))) answer = fp_dblnegate(answer);
  42.   return(answer);
  43. }
  44.  
  45.  
  46. int fp_dbllessthan(dblfixpoint x, dblfixpoint y)
  47. {
  48.   int bothneg, xneg, yneg;
  49.   xneg = fp_dblnegative(x);
  50.   yneg = fp_dblnegative(y);
  51.   bothneg = xneg && yneg;
  52.   if (xneg && !yneg) return 1;
  53.   if (yneg && !xneg) return 0;
  54.   if (bothneg) {
  55.     x = fp_dblnegate(x);
  56.     y = fp_dblnegate(y);
  57.   }
  58.   if (x.hi < y.hi) return !bothneg;
  59.   if (y.hi < x.hi) return  bothneg;
  60.   if (x.lo < y.lo) return !bothneg;
  61.   return bothneg;
  62. }
  63.  
  64. fixpoint fp_trunc(dblfixpoint a)
  65. {
  66.   int hi = (a.hi << LOBITS);
  67.   int lo = (a.lo >> LOBITS);
  68.  
  69.   if ((hi >> LOBITS) != a.hi) {
  70.      printf("fp_trunc() Overflow converting hibits 0x%08x to 0x%08x fixpoint in (%d,%d) bits\n", a.hi, hi, HIBITS, LOBITS);
  71.   }
  72.  
  73.   if (a.neg)
  74.      return (-(hi + lo));
  75.   else
  76.      return (hi + lo);
  77. }
  78.  
  79.  
  80. unsigned int add_with_carry(unsigned int a, unsigned int b,
  81.                                      int carry_in, int *carry_out)
  82. {
  83.   int ahi, bhi;
  84.   unsigned int answer;
  85.  
  86.   *carry_out = 0;
  87.  
  88.   ahi = (0x80000000 & a) ? 1 : 0;   /* Is high bit on? */
  89.   bhi = (0x80000000 & b) ? 1 : 0;
  90.  
  91.   a &= 0x7fffffff;
  92.   b &= 0x7fffffff;
  93.  
  94.   answer = a + b + carry_in;      /* this can't overflow (I think) */
  95.   if (answer & 0x80000000) {
  96.      if (ahi && bhi) *carry_out = 1;    /* Hi bit is on, leave it on */
  97.      else if (ahi || bhi) {                /* Turn hi bit off, turn on carry */
  98.         *carry_out = 1;
  99.         answer &= 0x7fffffff;
  100.      }
  101.   }
  102.   else {                    /* else (if answer high bit is off) */
  103.      if (ahi && bhi) *carry_out = 1;
  104.      else if (ahi || bhi) answer |= 0x80000000;
  105.   }
  106.   return(answer);
  107. }
  108.  
  109.  
  110. dblfixpoint fp_dbladd(dblfixpoint a, dblfixpoint b)
  111. {
  112.   dblfixpoint answer;
  113.  
  114.   if (verbose) printf("\nfpdbladd\n");
  115.  
  116.   if ((a.neg && b.neg) || (!a.neg && !b.neg)) {
  117.      int carry;
  118.      answer.neg = a.neg;
  119.      answer.lo = add_with_carry(a.lo, b.lo, 0, &carry);
  120.  
  121.      if ((answer.lo >> 2*LOBITS) && verbose)
  122.         printf("  Lobits overflow by 0x%x  (ok)\n", (answer.lo >> 2*LOBITS));
  123.  
  124.      /*This puts lobit overflow into .hi, and removes from .lo */
  125.      answer.hi = a.hi + b.hi + (answer.lo >> 2*LOBITS) + carry;
  126.      answer.lo &= (LOMASK | (LOMASK << LOBITS));
  127.   }
  128.   else {
  129.      if (a.neg) {
  130.         unsigned int tmp;
  131.         if (verbose) printf("\tCase: a.neg, b.pos, a<b, swapping\n");
  132.         a.neg = 0; b.neg =1;
  133.         tmp = a.hi; a.hi = b.hi; b.hi = tmp;
  134.         tmp = a.lo; a.lo = b.lo; b.lo = tmp;
  135.      }
  136.      if (a.hi < b.hi) {
  137.         if (a.lo <= b.lo) {
  138.           if (verbose) printf("\tCase: a.pos, b.neg, a.hi<b.hi, a.lo<=b.lo \n");
  139.           answer.neg = 1;
  140.           answer.lo = b.lo - a.lo;
  141.           answer.hi = b.hi - a.hi;
  142.         }
  143.         else {
  144.           if (verbose) printf("\tCase: a.pos, b.neg, a.hi<b.hi, a.lo > b.lo \n");
  145.           answer.neg = 1;
  146.           answer.lo = (b.lo - a.lo) & (LOMASK | (LOMASK << LOBITS));
  147.           answer.hi = b.hi - a.hi - 1;
  148.         }
  149.      }
  150.      else if ((a.hi == b.hi) && (a.lo < b.lo)) {
  151.         if (verbose) printf("\tCase: a.pos, b.neg, a.hi = b.hi, a.lo < b.lo \n");
  152.           answer.neg = 1;
  153.           answer.lo = b.lo - a.lo;
  154.           answer.hi = 0;
  155.      }
  156.      else {
  157.         if (a.lo >= b.lo) {
  158.           if (verbose) printf("\tCase: a.pos, b.neg, a.hi > b.hi, a.lo >= b.lo\n");
  159.           answer.neg = 0;
  160.           answer.lo = a.lo - b.lo;
  161.           answer.hi = a.hi - b.hi;
  162.         }
  163.         else {
  164.           if (verbose) printf("\tCase: a.pos, b.neg, a.hi > b.hi, a.lo < b.lo\n");
  165.           answer.neg = 0;
  166.           answer.lo = (a.lo - b.lo) & (LOMASK | (LOMASK << LOBITS));
  167.           answer.hi = a.hi - b.hi - 1;
  168.         }
  169.      }
  170.   }
  171.   return(answer);
  172. }
  173.  
  174.